package com.simin.base.easy.adapter.status;

import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.simin.base.easy.EasyRecyclerView;
import com.simin.base.easy.adapter.IHeaderFooterView;
import com.simin.base.easy.adapter.IRecyclerAdapter;


/**
 * Created by wsm on 2019/8/18.
 */
public class DefaultEventDelegate implements EventDelegate {
    private IRecyclerAdapter adapter;
    private EventFooter footer;

    private OnLoadMoreListener mLoadMoreListener;

    private boolean isLoadingMore = false;

    private boolean hasLoadMore = false;

    private int status = STATUS_INITIAL;
    private static final int STATUS_INITIAL = 291;
    private static final int STATUS_LOAD_MORE = 260;
    private static final int STATUS_NO_MORE = 408;
    private static final int STATUS_ERROR = 732;

    public DefaultEventDelegate(IRecyclerAdapter adapter) {
        this.adapter = adapter;
        footer = new EventFooter();
        adapter.addFooter(footer);
    }

    public void onMoreViewShowed() {
        log("onMoreViewShowed");
        if (!isLoadingMore && mLoadMoreListener != null) {
            isLoadingMore = true;
            mLoadMoreListener.onLoadMore();
        }
    }

    public void onErrorViewShowed() {
        if (mLoadMoreListener != null) mLoadMoreListener.onErrorLoadMore();
    }

    public void onErrorViewClicked() {
        if (mLoadMoreListener != null) mLoadMoreListener.onErrorMoreClick();
    }

    public void onNoMoreViewShowed() {
        if (mLoadMoreListener != null) mLoadMoreListener.onNoMoreData();
    }

    //-------------------5个状态触发事件-------------------
    @Override
    public void addData(int length) {
        log("addData" + length);
        if (hasLoadMore) {
            if (length == 0) {
                //当添加0个时，认为已结束加载到底
                if (status == STATUS_INITIAL || status == STATUS_LOAD_MORE) {
                    footer.showNoMore();
                    status = STATUS_NO_MORE;
                }
            } else {
                //当Error或初始时。添加数据，如果有More则还原。
                footer.showLoadMore();
                status = STATUS_LOAD_MORE;
            }
        }
        isLoadingMore = false;
    }

    @Override
    public void clear() {
        log("clear");
        status = STATUS_INITIAL;
        footer.hide();
        isLoadingMore = false;
    }

    @Override
    public void showNoMore() {
        log("stopLoadMore");
        footer.showNoMore();
        status = STATUS_NO_MORE;
        isLoadingMore = false;
    }

    @Override
    public void errorLoadMore() {
        log("pauseLoadMore");
        footer.showErrorLoadMore();
        status = STATUS_ERROR;
        isLoadingMore = false;
    }
    
    @Override
    public void setLoadMoreViews(View loadingView, View noMoreDataView, View errorLoadView) {
        if (loadingView != null) {
            hasLoadMore = true;
            footer.setMoreView(loadingView);
        }
        if (noMoreDataView != null) {
            noMoreDataView.setVisibility(View.GONE);
            footer.setNoMoreView(noMoreDataView);
        }
        if (errorLoadView != null) {
            errorLoadView.setVisibility(View.GONE);
            footer.setErrorLoadMoreView(errorLoadView);
        }
        // 为了处理setMore之前就添加了数据的情况
        if (adapter.getCount() > 0) {
            addData(adapter.getCount());
        }
        log("setMore");
    }

    @Override
    public void setOnLoadMoreListener(OnLoadMoreListener listener) {
        mLoadMoreListener = listener;
    }

    @Override
    public void showLoadMore() {
        isLoadingMore = false;
        footer.showLoadMore();
        status = STATUS_LOAD_MORE;
        onMoreViewShowed();
    }

    private class EventFooter implements IHeaderFooterView {
        private View moreView = null;
        private View noMoreView = null;
        private View errorView = null;
        private FrameLayout mStatusContainer;

        private int flag = STATUS_HIDE;
        public static final int STATUS_HIDE = 0;
        public static final int STATUS_SHOW_LOAD_MORE = 1;
        public static final int STATUS_SHOW_ERROR_LOAD_MORE = 2;
        public static final int STATUS_SHOW_NO_MORE = 3;

        public boolean skipError = false;
        public boolean skipNoMore = false;

        public EventFooter() {
        }

        @Override
        public View onCreateView(ViewGroup parent) {
            log("onCreateView");
            if (mStatusContainer != null) {
                return mStatusContainer;
            }
            mStatusContainer = new FrameLayout(parent.getContext());
            mStatusContainer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            if (moreView != null) {
                mStatusContainer.addView(moreView);
            }
            if (noMoreView != null) {
                mStatusContainer.addView(noMoreView);
            }
            if (errorView != null) {
                mStatusContainer.addView(errorView);
                errorView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        onErrorViewClicked();
                    }
                });
            }
            return mStatusContainer;
        }

        @Override
        public void onBindView(View headerView) {
            log("onBindView");
            headerView.post(new Runnable() {
                @Override
                public void run() {
                    refreshStatus();
                    switch (flag) {
                        case STATUS_SHOW_LOAD_MORE:
                            onMoreViewShowed();
                            break;
                        case STATUS_SHOW_NO_MORE:
                            if (!skipNoMore) onNoMoreViewShowed();
                            skipNoMore = false;
                            break;
                        case STATUS_SHOW_ERROR_LOAD_MORE:
                            if (!skipError) onErrorViewShowed();
                            skipError = false;
                            break;
                    }
                }
            });
        }

        public void refreshStatus() {
            switch (flag) {
                case STATUS_SHOW_LOAD_MORE:
                    setVisibility(moreView, true);
                    setVisibility(noMoreView, false);
                    setVisibility(errorView, false);
                    break;
                case STATUS_SHOW_ERROR_LOAD_MORE:
                    setVisibility(moreView, false);
                    setVisibility(noMoreView, false);
                    setVisibility(errorView, true);
                    break;
                case STATUS_SHOW_NO_MORE:
                    setVisibility(moreView, false);
                    setVisibility(noMoreView, true);
                    setVisibility(errorView, false);
                    break;
            }
        }

        private void setVisibility(View view, boolean visible) {
            if (view != null) {
                view.setVisibility(visible ? View.VISIBLE : View.GONE);
            }
        }

        public void showErrorLoadMore() {
            log("footer showError");
            skipError = true;
            flag = STATUS_SHOW_ERROR_LOAD_MORE;
            if (adapter.getItemCount() > 0)
                adapter.notifyItemChanged(adapter.getItemCount() - 1);
        }

        public void showLoadMore() {
            log("footer showMore");
            flag = STATUS_SHOW_LOAD_MORE;
            if (adapter.getItemCount() > 0)
                adapter.notifyItemChanged(adapter.getItemCount() - 1);
        }

        public void showNoMore() {
            log("footer showNoMore");
            skipNoMore = true;
            flag = STATUS_SHOW_NO_MORE;
            if (adapter.getItemCount() > 0)
                adapter.notifyItemChanged(adapter.getItemCount() - 1);
        }
        
        //初始化
        public void hide() {
            log("footer hide");
            flag = STATUS_HIDE;
            if (adapter.getItemCount() > 0)
                adapter.notifyItemChanged(adapter.getItemCount() - 1);
        }
        
        
        public void setMoreView(View moreView) {
            this.moreView = moreView;
        }

        public void setNoMoreView(View noMoreView) {
            if(mStatusContainer!=null&&this.noMoreView!=null){
                mStatusContainer.removeView(this.noMoreView);
                if(noMoreView.getParent()!=null&&noMoreView.getParent() instanceof ViewGroup){
                    ((ViewGroup) noMoreView.getParent()).removeView(noMoreView);
                }
                mStatusContainer.addView(noMoreView);
            }
            this.noMoreView = noMoreView;
        }

        public void setErrorLoadMoreView(View errorView) {
            this.errorView = errorView;
        }

        @Override
        public int hashCode() {
            return flag + 13589;
        }
    }


    private static void log(String content) {
        if (EasyRecyclerView.DEBUG) {
            Log.i(EasyRecyclerView.TAG, content);
        }
    }
}
